#if !defined(MEM_POOL_2_H)
#define MEM_POOL_2_H

#include <iostream>
#include <malloc.h>
#include <time.h>

using namespace std;

namespace mempool_2
{
    class A
    {
    private:
        /// @brief 指向下一个空间
        A *next;

        /// @brief 总是指向一块分配出去的内存首地址
        static A *m_FreePos;

        /// @brief 一次分配多少倍空间
        static int m_sTrunckCount;

    public:
        static void *operator new(size_t size);
        static void operator delete(void *p);

        /// @brief 分配计数器
        static int m_Count;

        /// @brief malloc计数统计
        static int m_MallocCount;
    };

    // init
    int A::m_Count = 0;
    int A::m_MallocCount = 0;
    A *A::m_FreePos = nullptr;
    int A::m_sTrunckCount = 5;

    void *A::operator new(size_t size)
    {
        A *tmplink;
        // 若待分配空间为空
        if (m_FreePos == nullptr)
        {
            // 一次分配5倍
            size_t realsize = m_sTrunckCount * size;
            // 分配空间
            m_FreePos = reinterpret_cast<A *>(new char[realsize]);
            tmplink = m_FreePos;
            // 将空间逐个串联成链表
            for (; tmplink != &m_FreePos[m_sTrunckCount - 1]; ++tmplink)
                tmplink->next = tmplink + 1;
            tmplink->next = nullptr;
            ++m_MallocCount;
        }
        // 返回当前待分配空间
        tmplink = m_FreePos;
        m_FreePos = m_FreePos->next;
        ++m_Count;
        return tmplink;
    }

    void A::operator delete(void *p)
    {
        // 将要释放的内存块的next指向空闲块（使其替代原本空闲块指针指向的块）
        (static_cast<A *>(p)->next) = m_FreePos;
        // 将空闲块指针指向释放的内存块
        m_FreePos = static_cast<A *>(p);
    }

};

#endif // MEM_POOL_2_H
